package com.jiawa.train.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jiawa.train.business.domain.DailyTrainCarriage;
import com.jiawa.train.business.domain.DailyTrainCarriageExample;
import com.jiawa.train.business.domain.Train;
import com.jiawa.train.business.domain.TrainCarriage;
import com.jiawa.train.business.mapper.DailyTrainCarriageMapper;
import com.jiawa.train.business.req.DailyTrainCarriageQueryReq;
import com.jiawa.train.business.req.DailyTrainCarriageSaveReq;
import com.jiawa.train.business.resp.DailyTrainCarriageQueryResp;
import com.jiawa.train.business.service.DailyTrainCarriageService;
import com.jiawa.train.business.service.TrainCarriageService;
import com.jiawa.train.common.exception.BusinessException;
import com.jiawa.train.common.exception.BusinessExceptionEnum;
import com.jiawa.train.common.resp.PageResp;
import com.jiawa.train.common.util.SnowUtil;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author zzl
 * @version 1.0
 */
@Service
public class DailyTrainCarriageServiceImpl implements DailyTrainCarriageService {
    private static final Logger LOG = LoggerFactory.getLogger(DailyTrainCarriageServiceImpl.class);

    @Resource
    private DailyTrainCarriageMapper dailyTrainCarriageMapper;
    @Resource
    private TrainCarriageService trainCarriageService;
    @Override
    public void save(DailyTrainCarriageSaveReq req) {
        DateTime now = DateTime.now();
        DailyTrainCarriage dailyTrainCarriage = BeanUtil.copyProperties(req, DailyTrainCarriage.class);
        if(ObjectUtil.isNull(dailyTrainCarriage.getId())) {
            if(isExist(dailyTrainCarriage)) {
                throw new BusinessException(BusinessExceptionEnum.TRAIN_CARRIAGE_IS_EXIST);
            } else {
                dailyTrainCarriage.setId(SnowUtil.getSnowflakeNextId());
                dailyTrainCarriage.setCreateTime(now);
                dailyTrainCarriage.setUpdateTime(now);
                dailyTrainCarriageMapper.insert(dailyTrainCarriage);
            }
        } else {
            dailyTrainCarriage.setUpdateTime(now);
            dailyTrainCarriageMapper.updateByPrimaryKeySelective(dailyTrainCarriage);
        }
    }

    /**
     * 分页查询每日高铁车厢数据
     * @param req
     * @return
     */
    @Override
    public PageResp<DailyTrainCarriageQueryResp> queryList(DailyTrainCarriageQueryReq req) {
        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        dailyTrainCarriageExample.setOrderByClause("date asc, train_code asc, `index` asc");
        DailyTrainCarriageExample.Criteria criteria = dailyTrainCarriageExample.createCriteria();
        if(ObjectUtil.isNotNull(req.getDate())) {
            criteria.andDateEqualTo(req.getDate());
        }
        if(ObjectUtil.isNotNull(req.getTrainCode())) {
            criteria.andTrainCodeEqualTo(req.getTrainCode());
        }

        LOG.info("查询页码：{}", req.getPage());
        LOG.info("每页条数：{}", req.getSize());
        PageHelper.startPage(req.getPage(), req.getSize());
        List<DailyTrainCarriage> dailyTrainCarriageList = dailyTrainCarriageMapper.selectByExample(dailyTrainCarriageExample);

        PageInfo<DailyTrainCarriage> pageInfo = new PageInfo<>(dailyTrainCarriageList);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        List<DailyTrainCarriageQueryResp> dailyTrainCarriageQueryRespList = BeanUtil.copyToList(dailyTrainCarriageList, DailyTrainCarriageQueryResp.class);

        PageResp<DailyTrainCarriageQueryResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(dailyTrainCarriageQueryRespList);

        return pageResp;
    }

    @Override
    public void delete(Long id) {
        dailyTrainCarriageMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据日期和高铁车次生成每日车厢数据
     * @param date
     * @param train
     */
    @Transactional
    @Override
    public void genDailyTrainCarriage(Date date, Train train) {
        LOG.info("生成日期【{}】车次【{}】的车厢信息开始", DateUtil.formatDate(date), train.getCode());

        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        dailyTrainCarriageExample.createCriteria()
                .andDateEqualTo(date)
                .andTrainCodeEqualTo(train.getCode());
        // 1.删除指定日期和车次的车厢数据
        dailyTrainCarriageMapper.deleteByExample(dailyTrainCarriageExample);

        // 2.查询指定日期和车次的车厢数据
        List<TrainCarriage> trainCarriageList = trainCarriageService.selectByTrainCode(train.getCode());
        if(CollUtil.isEmpty(trainCarriageList)) {
            LOG.info("火车车厢基础数据为空");
            return;
        }

        // 3.遍历高铁每日车厢并插入数据
        DateTime now = DateTime.now();
        for(TrainCarriage trainCarriage : trainCarriageList) {
            DailyTrainCarriage dailyTrainCarriage = BeanUtil.copyProperties(trainCarriage, DailyTrainCarriage.class);
            dailyTrainCarriage.setId(SnowUtil.getSnowflakeNextId());
            dailyTrainCarriage.setDate(date);
            dailyTrainCarriage.setCreateTime(now);
            dailyTrainCarriage.setUpdateTime(now);
            dailyTrainCarriageMapper.insert(dailyTrainCarriage);
        }

        LOG.info("生成日期【{}】车次【{}】的车厢信息结束", DateUtil.formatDate(date), train.getCode());
    }

    /**
     * 根据日期、车次、座位类型，查询每日车次对应的车厢数据
     * @param date
     * @param trainCode
     * @param seatType
     * @return
     */
    @Override
    public List<DailyTrainCarriage> selectBySeatType(Date date, String trainCode, String seatType) {
        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        dailyTrainCarriageExample.createCriteria()
                .andDateEqualTo(date)
                .andTrainCodeEqualTo(trainCode)
                .andSeatTypeEqualTo(seatType);
        return dailyTrainCarriageMapper.selectByExample(dailyTrainCarriageExample);
    }

    /**
     * 判断每日车厢是否存在
     * @param dailyTrainCarriage
     * @return
     */
    private boolean isExist(DailyTrainCarriage dailyTrainCarriage) {
        DailyTrainCarriageExample dailyTrainCarriageExample = new DailyTrainCarriageExample();
        dailyTrainCarriageExample.createCriteria()
                .andDateEqualTo(dailyTrainCarriage.getDate())
                .andTrainCodeEqualTo(dailyTrainCarriage.getTrainCode());
        List<DailyTrainCarriage> list = dailyTrainCarriageMapper.selectByExample(dailyTrainCarriageExample);
        if(CollUtil.isNotEmpty(list)) return true;
        else return false;
    }
}
